﻿using Castle.DynamicProxy;
using CNKI.TPI.Web.Admin.IBLL;
using CNKI.TPI.Web.Admin.IDAO;
using CNKI.TPI.Web.Base;
using CNKI.TPI.Web.Search.IDAO;
using CNKI.TPI.Web.Search.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace CNKI.TPI.Web.Admin.BLL
{
    public class UserCenterService : BaseService, IUserCenterService
    {
        private IUserDBDAO userDBDAO = null;
        private IUserCenterDAO userCenterDAO = null;
        private ICategoryDAO categoryDAO = null;
        public UserCenterService(IUserDBDAO userDBDAO, IUserCenterDAO userCenterDAO, ICategoryDAO categoryDAO)
        {
            this.userDBDAO = this.generator.CreateInterfaceProxyWithTarget<IUserDBDAO>(userDBDAO, new IInterceptor[] { new LogInterceptor() });
            this.userCenterDAO = this.generator.CreateInterfaceProxyWithTarget<IUserCenterDAO>(userCenterDAO, new IInterceptor[] { new LogInterceptor() });
            this.categoryDAO = this.generator.CreateInterfaceProxyWithTarget<ICategoryDAO>(categoryDAO, new IInterceptor[] { new LogInterceptor() });
        }
        /// <summary>
        /// 获取检索数据
        /// </summary>
        /// <param name="DBname"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="startIndex"></param>
        /// <param name="pagecount"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public DataTable GetSearchPage(string DBname, DateTime? startDate, DateTime? endDate, int startIndex, int pagecount, out int count)
        {
            DataTable dt = null;
            IList<SYS_CMS_DATABASE> list = userDBDAO.GetDatabaseList();
            IList<int> strlist = getdbID(list, DBname);
            dt = userCenterDAO.GetSearchPage(strlist, startDate, endDate, startIndex, pagecount, out count);
            dt = dealDataBaseName(dt, list);
            return dt;

        }

        /// <summary>
        /// 获取检索数据
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="DBname"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="startIP"></param>
        /// <param name="endIP"></param>
        /// <returns></returns>
        public DataTable GetSearchPage(string userid, string DBname, DateTime? startDate, DateTime? endDate, string startIP, string endIP)
        {
            DataTable dt = null;
            IList<SYS_CMS_DATABASE> list = userDBDAO.GetDatabaseList();
            IList<int> strlist = getdbID(list, DBname);
            dt = userCenterDAO.GetSearchPage(strlist, startDate, endDate, userid, startIP, endIP);
            dt = dealDataBaseName(dt, list);
            return dt;

        }
        /// <summary>
        /// 获取浏览数据
        /// </summary>
        /// <param name="DBname"></param>
        /// <param name="title"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="startIndex"></param>
        /// <param name="pagecount"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public DataTable GetViewPage(string DBname, string title, DateTime? startDate, DateTime? endDate, int startIndex, int pagecount, out int count)
        {
            DataTable dt = null;
            IList<SYS_CMS_DATABASE> list = userDBDAO.GetDatabaseList();
            IList<int> strlist = getdbID(list, DBname);
            dt = userCenterDAO.GetViewPage(strlist, title, startDate, endDate, startIndex, pagecount, out count);
            dt = dealDataBaseName(dt, list);
            //if (dt != null)
            //{
            //    string strTitle = null;
            //    foreach (DataRow dr in dt.Rows)
            //    {
            //        strTitle = dr["Title"] != null ? dr["Title"].ToString() : "";
            //        strTitle = ColumnAliasHelper.ChangeStr(strTitle);
            //        strTitle = StringHelper.DealInfo(strTitle);
            //        dr["Title"] = strTitle;
            //    }
            //}
            return dt;

        }

        /// <summary>
        /// 获取浏览数据
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="DBname"></param>
        /// <param name="title"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="startIP"></param>
        /// <param name="endIP"></param>
        /// <returns></returns>
        public DataTable GetViewPage(string userid, string DBname, string title, DateTime? startDate, DateTime? endDate, string startIP, string endIP)
        {
            DataTable dt = null;
            IList<SYS_CMS_DATABASE> list = userDBDAO.GetDatabaseList();
            IList<int> strlist = getdbID(list, DBname);
            dt = userCenterDAO.GetViewPage(strlist, title, startDate, endDate, userid, startIP, endIP);
            dt = dealDataBaseName(dt, list);
            return dt;

        }
        /// <summary>
        /// 获取下载数据
        /// </summary>
        /// <param name="DBname"></param>
        /// <param name="title"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="startIndex"></param>
        /// <param name="pagecount"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public DataTable GetDownPage(string DBname, string title, DateTime? startDate, DateTime? endDate, int startIndex, int pagecount, out int count)
        {
            DataTable dt = null;
            IList<SYS_CMS_DATABASE> list = userDBDAO.GetDatabaseList();
            IList<int> strlist = getdbID(list, DBname);
            dt = userCenterDAO.GetDownPage(strlist, title, startDate, endDate, startIndex, pagecount, out count);
            dt = dealDataBaseName(dt, list);
            //if (dt != null)
            //{
            //    string strTitle = null;
            //    foreach (DataRow dr in dt.Rows)
            //    {
            //        strTitle = dr["Title"] != null ? dr["Title"].ToString() : "";
            //        strTitle = ColumnAliasHelper.ChangeStr(strTitle);
            //        strTitle = StringHelper.DealInfo(strTitle);
            //        dr["Title"] = strTitle;
            //    }
            //}
            return dt;

        }
        /// <summary>
        /// 获取下载数据
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="DBname"></param>
        /// <param name="title"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="startIP"></param>
        /// <param name="endIP"></param>
        /// <returns></returns>
        public DataTable GetDownPage(string userid, string DBname, string title, DateTime? startDate, DateTime? endDate, string startIP, string endIP)
        {
            DataTable dt = null;
            IList<SYS_CMS_DATABASE> list = userDBDAO.GetDatabaseList();
            IList<int> strlist = getdbID(list, DBname);
            dt = userCenterDAO.GetDownPage(strlist, title, startDate, endDate, userid, startIP, endIP);
            dt = dealDataBaseName(dt, list);
            return dt;

        }
        private IList<int> getdbID(IList<SYS_CMS_DATABASE> list, string DBname)
        {
            IList<int> strlist = new List<int>();
            if (!String.IsNullOrEmpty(DBname) && list != null && list.Count > 0)
            {
                IList<SYS_CMS_DATABASE> listdbid = list.Where(c => c.DatabaseName.Contains(DBname)).ToList();
                if (listdbid != null && listdbid.Count > 0)
                {

                    strlist = listdbid.Select(c => c.SysID).ToList();
                }
                else
                {
                    strlist.Add(-1);
                }
            }
            return strlist;

        }

        /// <summary>
        /// 处理查询结果
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        private DataTable dealDataBaseName(DataTable dt, IList<SYS_CMS_DATABASE> list)
        {
            try
            {
                if (dt != null && dt.Rows.Count > 0)
                {
                    dt.Columns["DbName"].MaxLength = 2000;
                    if (dt.Columns.Contains("DetailUrL"))//浏览历史处理 细缆URL
                    {
                        dt.Columns["DetailUrL"].MaxLength = 2000;
                    }
                    if (dt.Columns.Contains("SearchUrL"))//浏览历史处理 细缆URL
                    {
                        dt.Columns["SearchUrL"].MaxLength = 2000;
                    }
                    foreach (DataRow dr in dt.Rows)
                    {
                        string dbid = dr["DbID"].ToString();
                        string dbname = "";
                        if (dbid.IndexOf(',') > 0)
                        {
                            string[] strid = dbid.Split(',');
                            foreach (string item in strid)
                            {
                                dbname += getDataBaseName(int.Parse(item), list) + ",";
                            }
                            dbname = dbname.TrimEnd(',');
                        }
                        else
                        {
                            dbname = getDataBaseName(int.Parse(dbid), list);
                        }

                        dr["DbName"] = dbname;
                        if (dt.Columns.Contains("Str_Query"))//检索历史 处理检索条件
                        {
                            ProcessQueryString(dr);
                        }
                        if (dt.Columns.Contains("DetailUrL"))//浏览历史处理 细缆URL
                        {
                            dr["DetailUrL"] = getDetailUrl(int.Parse(dbid), list, dr);
                        }
                        if (dt.Columns.Contains("SearchUrL"))//浏览历史处理 细缆URL
                        {
                            dr["SearchUrL"] = getSearchUrl(dbid, list, dr);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return dt;
        }

        private static void ProcessQueryString(DataRow dr)
        {
            string query = dr["Str_Query"].ToString();
            query = Regex.Replace(query, @"(And +){0,1}\(SYS_FLD_CHECKSTATE.*?\)[^)]( +And){0,1}", "", RegexOptions.IgnoreCase);
            query = query.Replace("(", "").Replace(")", "").Trim();
            query = query.Replace(" Eq ", " = ").Replace(" GreaterThan ", " > ").Replace(" GreaterThanOrEqual ", " >= ").Replace(" LessThan ", " < ").Replace(" LessThanOrEqual ", " <= ").Trim();
            query = query.Replace(" = '?", " Like '");
            dr["Str_Query"] = query;
        }

        private string getDataBaseName(int dbid, IList<SYS_CMS_DATABASE> list)
        {
            string name = "";
            try
            {

                IList<SYS_CMS_DATABASE> listdbid = list.Where(c => c.SysID == dbid).ToList();
                if (listdbid != null && listdbid.Count > 0)
                {
                    name = listdbid[0].DatabaseName;
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return name;
        }

        /// <summary>
        /// 细缆url
        /// </summary>
        /// <param name="dbid"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        private string getDetailUrl(int dbid, IList<SYS_CMS_DATABASE> list, DataRow dr)
        {
            string urlstr = "";
            SYS_CMS_DATABASE obj = new SYS_CMS_DATABASE();
            try
            {

                IList<SYS_CMS_DATABASE> listdbid = list.Where(c => c.SysID == dbid).ToList();
                if (listdbid != null && listdbid.Count > 0)
                {
                    obj = listdbid[0];
                    urlstr = ResourceHelper.GetSingleSearchDetailURL(obj, dr);

                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return urlstr;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbid"></param>
        /// <param name="list"></param>
        /// <param name="dr"></param>
        /// <returns></returns>
        private string getSearchUrl(string dbid, IList<SYS_CMS_DATABASE> list, DataRow dr)
        {
            string urlstr = "";
            try
            {
                string searchType = dr["searchType"].ToString();
                string hostUrl = System.Web.HttpContext.Current.Request.ApplicationPath.TrimEnd('/') + "/";
                switch (searchType)
                {
                    
                    case "SingleSearch":
                        //单库检索
                        SYS_CMS_DATABASE obj = new SYS_CMS_DATABASE();
                        IList<SYS_CMS_DATABASE> listdbid = list.Where(c => c.SysID == int.Parse(dbid)).ToList();
                        if (listdbid != null && listdbid.Count > 0)
                        {
                            obj = listdbid[0];
                            
                            urlstr = hostUrl + "SingleSearch?id={0}&name={1}&displayDBName={2}&searchLog={3}&searchType={4}&topicCLSCode={5}&topicCLSNodeCode={6}";
                            urlstr = string.Format(urlstr, dbid, obj.DatabaseCode, obj.DatabaseName, dr["searchlogid"], (int)obj.SearchType, dr["TopicCLS"], dr["TopicNode"]);
                        }
                        break;
                    case "MultiSearch":
                        urlstr = hostUrl + "MultiSearch?searchLog="+ dr["searchlogid"];
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return urlstr;
        }
        /// <summary>
        /// 获取收藏分类类别
        /// </summary>
        /// <returns></returns>
        public DataTable GetFavoriteCategory(int startIndex, int pagecount, out int count)
        {
            string userCode = SessionHelper.GetUserInfo().UserCode;
            return userCenterDAO.GetFavoriteCategory(userCode, startIndex, pagecount, out count);
        }

        public DataTable GetFavoriteCategory()
        {
            string userCode = SessionHelper.GetUserInfo().UserCode;
            return userCenterDAO.GetFavoriteCategory(userCode);
        }

        /// <summary>
        /// 新增分类数据
        /// </summary>
        /// <param name="catename"></param>
        /// <param name="catestatus"></param>
        /// <param name="sortno"></param>
        /// <param name="usercode"></param>
        /// <returns></returns>
        public bool InsertFavoriteCategory(string catename, int catestatus)
        {
            string usercode = SessionHelper.GetUserInfo().UserCode;
            int sortno = userCenterDAO.GetMaxSort() + 1;
            return userCenterDAO.InsertFavoriteCategory(catename, catestatus, sortno, usercode);
        }
        /// <summary>
        /// 更新分类名称
        /// </summary>
        /// <param name="catename"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool UpdateFavoriteCategoryName(string catename, int id)
        {
            return userCenterDAO.UpdateFavoriteCategoryName(catename, id);
        }
        /// <summary>
        /// 更新分类顺序
        /// </summary>
        /// <param name="sortno"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool UpdateFavoriteCategorySort(int sortno, int id)
        {
            return userCenterDAO.UpdateFavoriteCategorySort(sortno, id);
        }
        /// <summary>
        /// 删除分类
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DelFavoriteCategory(int id)
        {
            return userCenterDAO.DelFavoriteCategory(id);
        }
        /// <summary>
        ///判断分类名称是否重复
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public int IsExistFavName(string name)
        {
            string userCode = SessionHelper.GetUserInfo().UserCode;
            return userCenterDAO.IsExistFavName(userCode, name);
        }
        /// <summary>
        /// 新增收藏记录
        /// </summary>
        /// <param name="catename"></param>
        /// <param name="catestatus"></param>
        /// <param name="sortno"></param>
        /// <param name="usercode"></param>
        /// <returns></returns>
        public bool InsertFavoriteFolder(int favCateID, string dbCode, string dbName, string recid, string recTitle)
        {
            return userCenterDAO.InsertFavoriteFolder(favCateID, dbCode, dbName, recid, recTitle);
        }
        /// <summary>
        /// 获取收藏列表
        /// </summary>
        /// <returns></returns>
        public DataTable GetFavoriteFolder(int catid, string dbname, string title, DateTime? startDate, DateTime? endDate, int startIndex, int pagecount, out int count)
        {
            DataTable dt = new DataTable();
            count = 0;
            try
            {
               
                IList<SYS_CMS_DATABASE> list = userDBDAO.GetDatabaseList();
                dt = userCenterDAO.GetFavoriteFolder(catid, dbname, title, startDate, endDate, startIndex, pagecount, out count);
                if (dt != null && dt.Rows.Count > 0)
                {
                    dt.Columns["DetailUrL"].MaxLength = 2000;
                    foreach (DataRow dr in dt.Rows)
                    {
                        IList<SYS_CMS_DATABASE> listdbid = list.Where(c => c.DatabaseCode == dr["DbCode"].ToString()).ToList();
                        if (listdbid != null && listdbid.Count > 0)
                        {
                            SYS_CMS_DATABASE obj = listdbid[0];
                            dr["DetailUrL"] = ResourceHelper.GetSingleSearchDetailURLForFav(obj, dr);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return dt;
        }
        /// <summary>
        /// 更新收藏记录
        /// </summary>
        /// <param name="catename"></param>
        /// <param name="catestatus"></param>
        /// <param name="sortno"></param>
        /// <param name="usercode"></param>
        /// <returns></returns>
        public bool UpdateFavoriteFolder(int favCateID, int floderid)
        {
            return userCenterDAO.UpdateFavoriteFolder(favCateID, floderid);
        }
        /// <summary>
        /// 删除收藏记录
        /// </summary>
        /// <param name="catename"></param>
        /// <param name="catestatus"></param>
        /// <param name="sortno"></param>
        /// <param name="usercode"></param>
        /// <returns></returns>
        public bool DelFavoriteFolder(string  floderid)
        {
            bool f = false;
            if (floderid.IndexOf(',') > 0)
            {
                f = userCenterDAO.DelFavoriteFolderBath(floderid);
            }
            else
            {
                f = userCenterDAO.DelFavoriteFolder(int.Parse(floderid));
            }
            return f;
        }
        /// <summary>
        /// 取消收藏
        /// </summary>
        /// <param name="recid"></param>
        /// <returns></returns>
        public bool UpdateFavStatusByRecID(int recid)
        {

            return userCenterDAO.UpdateFavStatusByRecID(recid);
        }
         /// <summary>
        /// 根据数据库code获取该数据库的收藏记录
        /// </summary>
        /// <param name="dbcode"></param>
        /// <returns></returns>
        public DataTable GetFavFolderList(string dbcode)
        {
            return userCenterDAO.GetFavFolderList(dbcode);
        }

        public void GetSingleSearchLogDetail(string dbid, string dbCode, SearchType searchType, int searchLogID, IList<SearchQuery> searchQueryList, out int clsID, out string categoryNodeCode, out string order)
        {
            clsID = -1;
            categoryNodeCode = "";
            string classCode = "";
            string str_dbid = "";
            GetSearchQuery(searchLogID, searchQueryList, out order, out classCode, out str_dbid);
            if (searchQueryList != null && searchQueryList.Count > 0 && searchType == SearchType.TPI)
            {
                IList<CLS> clsList = categoryDAO.GetCategroyTypeAll(dbCode);
                IList<SearchQuery> categoryQuery = null;
                CLS selectCls = null;
                foreach (CLS cls in clsList)
                {
                    categoryQuery = searchQueryList.Where(c => c.Key == cls.Expression).ToList();
                    if (categoryQuery != null && categoryQuery.Count > 0)
                    {
                        selectCls = cls;
                        break;
                    }
                }
                if (categoryQuery != null && categoryQuery.Count > 0)
                {
                    clsID = selectCls.SysID;
                    categoryNodeCode = ProcessCatNodeCode(clsID, dbCode, string.Join(",", categoryQuery.Select(c => c.Text.Substring(0, c.Text.Length - 1))));
                    foreach (SearchQuery item in categoryQuery)
                    {
                        searchQueryList.Remove(item);
                    }
                }
            }
        }

        public void GetMultiSearchLogDetail(int searchLogID, IList<SearchQuery> searchQueryList, out string order, out string classCode, out string dbid)
        {
            GetSearchQuery(searchLogID, searchQueryList, out order, out classCode, out dbid);
        }

        private string ProcessCatNodeCode(int clsid, string dbcode, string catNodeCode)
        {
            string result = "";
            try
            {
                ArrayList catNodeList = new ArrayList();
                StringBuilder content = new StringBuilder();
                if (catNodeCode.Contains(','))
                {
                    catNodeList.AddRange(catNodeCode.Split(','));
                }
                else
                {
                    catNodeList.Add(catNodeCode);
                }

                foreach (string item in catNodeList)
                {
                    CLS_NODE node = categoryDAO.GetCategroy(dbcode, clsid, item);
                    if (node.SysCode.Length == 4)
                    {
                        content.AppendFormat("{0}|", item);
                    }
                    else
                    {
                        IList<string> syscodeList = new List<string>();
                        string syscode = node.SysCode;
                        do
                        {
                            syscode = syscode.Substring(0, syscode.Length - 4);
                            syscodeList.Add(syscode);
                        } while (syscode.Length != 4);
                        IList<CLS_NODE> nodeList = categoryDAO.GetCategroy(dbcode, clsid, syscodeList);
                        content.Append(string.Join(",", nodeList.Select(c=>c.Code)));
                        content.AppendFormat(",{0}|", item);
                    }
                }
                result = content.ToString();
                if (!string.IsNullOrEmpty(result))
                {
                    result = result.Substring(0, result.Length - 1);
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="searchLogID"></param>
        /// <param name="searchQueryList"></param>
        /// <param name="order"></param>
        private void GetSearchQuery(int searchLogID, IList<SearchQuery> searchQueryList, out string order, out string classCode, out string dbid)
        {
            order = "";
            classCode = "";
            dbid = "";
            SearchQuery searchQuery = null;
            DataTable dt = userCenterDAO.GetSearchLogInfo(searchLogID);
            if (dt != null && dt.Rows.Count > 0)
            {
                ProcessQueryString(dt.Rows[0]);
                string query = dt.Rows[0]["Str_Query"].ToString();
                order = dt.Rows[0]["Str_Order"].ToString();
                classCode = dt.Rows[0]["classCode"].ToString();
                dbid = dt.Rows[0]["dbid"].ToString();
                string[] queryList = Regex.Split(query, "(?=( And | Or ))", RegexOptions.ExplicitCapture);
                foreach (string item in queryList)
                {
                    searchQuery = new SearchQuery();
                    string item1 = item.Trim();
                    if (item1.StartsWith("Or"))
                    {
                        searchQuery.Type = SearchMatchType.Or;
                        item1 = item1.Substring(3);
                    }
                    else if (item1.StartsWith("And"))
                    {
                        searchQuery.Type = SearchMatchType.And;
                        item1 = item1.Substring(4);
                    }
                    string[] condition = Regex.Split(item1, "(?=( Like | <= | < | >= | > | = ))", RegexOptions.ExplicitCapture);
                    searchQuery.Key = condition[0].Trim();
                    
                    if (item1.Contains(" Like "))
                    {
                        searchQuery.ConditionType = ConditionType.Like;
                        searchQuery.Text = condition[1].Substring(7, condition[1].Length-8).Trim();
                    }
                    else if (item1.Contains(" <= "))
                    {
                        searchQuery.ConditionType = ConditionType.LessThanOrEqual;
                        searchQuery.Text = condition[1].Substring(5, condition[1].Length - 6).Trim();
                    }
                    else if (item1.Contains(" < "))
                    {
                        searchQuery.ConditionType = ConditionType.LessThan;
                        searchQuery.Text = condition[1].Substring(4, condition[1].Length - 5).Trim();
                    }
                    else if (item1.Contains(" >= "))
                    {
                        searchQuery.ConditionType = ConditionType.GreaterThanOrEqual;
                        searchQuery.Text = condition[1].Substring(5, condition[1].Length - 6).Trim();
                    }
                    else if (item1.Contains(" > "))
                    {
                        searchQuery.ConditionType = ConditionType.GreaterThan;
                        searchQuery.Text = condition[1].Substring(4, condition[1].Length - 5).Trim();
                    }
                    else if (item1.Contains(" = "))
                    {
                        searchQuery.ConditionType = ConditionType.Eq;
                        searchQuery.Text = condition[1].Substring(4, condition[1].Length - 5).Trim();
                    }
                    searchQueryList.Add(searchQuery);
                }
            }
        }
    }
}
